package config

import (
	"log"
	"time"

	"app/pkg"

	"github.com/go-ini/ini"
)

var (
	// server
	Debug    bool
	Domain   string
	Port     int
	Https    bool
	CertFile string
	KeyFile  string

	// limit
	LimitEnable bool
	MaxRequest  int
	LimitExpire time.Duration

	// cache
	CacheDriver   string
	RedisAddr     string
	RedisPassword string
	RedisDB       int

	// jwt
	JwtExpire time.Duration
	JwtSecret string

	// database
	Driver     string
	DataSource string
)

func InitConfig(filePath string) {
	file, err := ini.LoadSources(ini.LoadOptions{
		Loose: true,
	}, filePath)
	if err != nil {
		log.Fatal("read config file error: ", err)
	}
	LoadServer(file)
	LoadLimit(file)
	LoadJwt(file)
	LoadCache(file)
	LoadDatabase(file)

	// 保存配置文件，确保文件与内存同步
	if file.SaveTo(filePath) != nil {
		log.Fatal("write config file error: ", err)
	}

	file.WriteTo(log.Writer())
	log.Printf("JwtSecret: [%s]", JwtSecret)
}

func LoadServer(file *ini.File) {
	file.Section("server").Key("debug").Comment = "please set to false in production"
	Debug = file.Section("server").Key("debug").MustBool(true)
	Domain = file.Section("server").Key("domain").MustString("localhost")
	Port = file.Section("server").Key("port").MustInt(8080)
	Https = file.Section("server").Key("https").MustBool(false)
	KeyFile = file.Section("server").Key("key").MustString("./server.key")
	CertFile = file.Section("server").Key("cert").MustString("./server.crt")
}

func LoadLimit(file *ini.File) {
	LimitEnable = file.Section("limit").Key("enable").MustBool(false)
	MaxRequest = file.Section("limit").Key("max_request").MustInt(60)
	LimitExpire = file.Section("limit").Key("expire").MustDuration(time.Minute)
}

func LoadJwt(file *ini.File) {
	JwtExpire = file.Section("jwt").Key("expire").MustDuration(time.Hour)
	JwtSecret = file.Section("jwt").Key("secret").Validate(func(value string) string {
		if len(value) > 0 {
			return value
		}
		randStr, err := pkg.RandomAlphanumericString(64)
		if err != nil {
			log.Fatal(err)
			return ""
		}
		return randStr
	})
	file.Section("jwt").Key("secret").SetValue(JwtSecret)
}

func LoadCache(file *ini.File) {
	file.Section("cache").Key("driver").Comment = "memory | redis"
	CacheDriver = file.Section("cache").Key("driver").MustString("memory")
	RedisAddr = file.Section("cache").Key("addr").MustString("127.0.0.1:6379")
	RedisPassword = file.Section("cache").Key("password").MustString("")
	RedisDB = file.Section("cache").Key("db").MustInt(0)
}

func LoadDatabase(file *ini.File) {
	file.Section("database").Key("driver").Comment = "sqlite_go | sqlite | mysql"
	Driver = file.Section("database").Key("driver").MustString("sqlite_go")
	if Driver == "sqlite" || Driver == "sqlite_go" {
		DataSource = file.Section("database").Key("source").MustString(":memory:")
	}
}
